﻿using System;
using System.Configuration;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Security.Principal;
using System.Web;
using IntraVision.Web;
using IntraVision.Web.Security;
using Model;
using NotarialService.Classes;

public class LoginController : LoginController<NotarialServiceDataContext,User>
{
    public override void Default()
    {
        this.Authorized = new LoginEvent(AddLoginMessageToLog);
        RegisterScript("login/login.js");
        base.Default();
    }

    public override void Logout()
    {
        AddMessageToLog(Session[_UserKey] as User, EventLogOperationType.UserLogout);
        using (var dc = new NotarialServiceDataContext())
        {
            Logger.WriteLog(dc, LogOperationType.Logout, (Session[_UserKey] as User).Id, null, null);
        }
        base.Logout();
    }

    protected void AddLoginMessageToLog(object user)
    {
        AddMessageToLog(user, EventLogOperationType.UserLogin);
    }

    protected void AddMessageToLog(object user, EventLogOperationType operation)
    {
        if (user != null)
        {
            EventLog.AddToLog((user as User).Id, null, Request.UserHostAddress.ToString(), operation);
            using (var dc = new NotarialServiceDataContext())
            {
                Logger.WriteLog(dc, LogOperationType.Login, (user as User).Id, null, null);
            }
        }
    }

    protected override void AuthorizeViaIdentity()
    {
        // выход пользователя из системы
        if (Session["logout"] != null)
        {
            Session.Clear();

            ViewData["login"] = "";
            ViewData["password"] = "";

            RenderView();

            return;
        }

        var login = Context.User.Identity.Name;

        if (string.IsNullOrEmpty(login))
        {
            ViewData["login"] = "";
            ViewData["password"] = "";

            RenderView();
            return;
        }

        User user = null;

        using (var dc = new NotarialServiceDataContext())
        {

            // При использовании windows-авторизации пользователь авторизуется по его windows-логину
            try
            {
                user = dc.Users.Where(u => u.Login == login && !u.IsArchive).FirstOrDefault();
            }
            catch (Exception ex)
            {
                // может быть ошибка отутствия у пользователя прав к БД, т.к. это первый запрос, выполняющийся при логине
                ViewData["message"] = "WINDOWS_AUTHENTICATION_FAILED";
                ViewData["windowsautherror"] = ADUser.ErrorMessageFromException(ex, "Ошибка Windows авторизации");
                ViewData["login"] = "";
                ViewData["password"] = "";

                RenderView();
                return;
            }

            // если пользователь с заданным логином не найден, попытка его создания с параметрами из AD
            if (user == null)
            {
                string errorMessage = "";

                user = null;

                // получение записей AD из Identity по полному имени пользователя (DOMAIN\USERNAME)
                DirectoryEntry domainEntry = ADUser.GetDomainADEntry(Context.User.Identity, out errorMessage);
                DirectoryEntry userEntry = ADUser.GetUserADEntry(Context.User.Identity, out errorMessage);

                if (domainEntry == null || userEntry == null)
                {
                    RenderViewWithError("WINDOWS_AUTHENTICATION_FAILED", "Ошибка Windows авторизации: " + errorMessage);
                    return;
                }

                try { dc.Connection.Open(); }
                catch { }

                // создание пользователя с параметрами из AD
                SyncResult res = ADUser.UpdateUserFromAD((System.Data.SqlClient.SqlConnection)dc.Connection, domainEntry, userEntry, out errorMessage);

                if (dc.Connection.State == System.Data.ConnectionState.Open)
                    dc.Connection.Close();

                if (res == SyncResult.Error)
                {
                    RenderViewWithError("WINDOWS_AUTHENTICATION_FAILED", "Ошибка Windows авторизации: " + errorMessage);
                    return;
                }
                else
                    user = dc.Users.Where(u => u.Login == Context.User.Identity.Name).FirstOrDefault();
            }

            // логин полученного пользователя
            if (Authorized != null)
                Authorized(user);

            Session[_UserKey] = user;
            RedirectFromLoginPage(user as IUser);
        }
    }

    protected void RenderViewWithError(string message, string error)
    {
        ViewData["message"] = message;
        ViewData["windowsautherror"] = error;
        ViewData["login"] = "";
        ViewData["password"] = "";

        RenderView();
    }

    public void GetCurrentTime()
    {
        Response.Write(DateTime.Now.ToString("dd MMMM yyyy г. HH:mm"));
    }
}
